package com.dayu.finecomm.service;

import java.util.HashSet;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.dayu.finecomm.device.Device;
import com.dayu.finecomm.device.UdpDevice;
import com.dayu.finecomm.pojo.DeviceConfig;
import com.dayu.finecomm.source.CollectSource;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;

/**
 * @ClassName: HdUdpService
 * @Description:udp设备启动类
 * @author: 戴卫国
 * @date: 2018年2月23日 下午3:25:21
 * 
 * @Copyright: 2018 dayu Inc. All rights reserved.
 */
public class HdUdpService {

	Logger LOGGER = LoggerFactory.getLogger(HdUdpService.class);

	DeviceConfig config;
	Device handler;

	Map<String, ChannelHandlerContext> listeners;

	public HdUdpService(CollectSource stations, DeviceConfig config) {

		this.config = config;

		HashSet<String> protocols = new HashSet<>();
		protocols.addAll(config.protocols);

		if (config.type.equals("udp")) {
			handler = new UdpDevice(stations, protocols, config);
		}
	}

	/**
	 * @Title: bootstrap
	 * @Description: 启动监听
	 * @param: @return
	 * @param: @throws
	 *             InterruptedException
	 */
	public ChannelFuture bootstrap() throws InterruptedException {

		final EventLoopGroup group = new NioEventLoopGroup();

		Bootstrap b = new Bootstrap();
		b.option(ChannelOption.SO_RCVBUF, 6 * 1024 * 1024);
		b.channel(NioDatagramChannel.class).group(group);

		HashSet<String> protocols = new HashSet<>();
		protocols.addAll(config.protocols);

		b.handler(getHandler());

		ChannelFuture f = null;
		if ("127.0.0.1".equals(config.host)) {
			f = b.bind(config.port).sync();
		} else {
			f = b.bind(config.host, config.port).sync();
		}

		ChannelFuture cf = f.channel().closeFuture();

		cf.addListener(new GenericFutureListener<Future<? super Void>>() {

			@Override
			public void operationComplete(Future<? super Void> future) throws Exception {
				group.shutdownGracefully();
			}
		});

		return cf;
	}

	public Map<String, ChannelHandlerContext> getListeners() {
		return listeners;
	}

	public void setListeners(Map<String, ChannelHandlerContext> listeners) {
		this.listeners = listeners;
	}

	public Device getHandler() {
		return handler;
	}

}
